import { ref, computed } from 'vue'

export default function useShortcut(props, groupRef) {
  // 锚点高度
  const ANCHOR_HEIGHT = 18
  const scrollRef = ref(null)

  // 根据传入的data计算而来，拿到传入每个组的group-title即可
  // 注意计算属性的写法！
  const shortcutList = computed(() => {
    return props.data.map((group) => {
      return group.title
    })
  })

  const touch = {}

  function onShortcutTouchStart (e) {
    // 这里e.target不一定是li，当在索引框上方黑边拖动的时候 e.t就指向这个容器，而div c=shortcut明显没有dataset是个undefined,
    // 所以导致传入的anchorIndex是NaN,由于最终作用于scrollto函数所以在scrollTo中做判断
    // 拿到触摸时候li元素的索引
    const anchorIndex = parseInt(e.target.dataset.index)
    // start时候记录触摸到的Y坐标
    touch.y1 = e.touches[0].pageY
    // 将start的索引保存到touch对象中
    touch.anchorIndex = anchorIndex

    // 通过索引拿到需要滚动到的DOM元素 与move相同逻辑抽象到scrollTo
    // const targetEl = groupRef.value.children[anchorIndex]
    // 通过ref拿到scroll组件的实例，记得在setup中返回才可以
    // scrollRef.value对应的就是这个组件的实例，.scroll就是返回的scroll对象
    // const scroll = scrollRef.value.scroll
    // scroll.scrollToElement(targetEl, 0)

    scrollTo(anchorIndex)
  }

  /*
  * move实现逻辑start是根据索引拿到具体元素滚动到位置
  * 在start时是有一个初始的索引值，并且可以记录下start时手指触碰的纵坐标
  * 在move的时候也实时拿到手指触碰的纵坐标，然后（move纵坐标-start纵坐标）/ 每个锚点的高度，这样就得到了偏移了几个身位
  * 之后再根据之前的初始索引(start) + 偏移身位 求得了Move时候的一个索引
  * 再根据这个索引得到需要滚动到的元素即可
  * */
  function onShortcutTouchMove (e) {
    // move时的纵坐标
    touch.y2 = e.touches[0].pageY
    // 求得偏移量,偏移了几个字母  | 0 就是向下取整的写法等价 Math.floor
    const delta = (touch.y2 - touch.y1) / ANCHOR_HEIGHT | 0
    // 计算目标索引 = 初始索引+偏移量
    const anchorIndex = touch.anchorIndex + delta
    scrollTo(anchorIndex)
  }

  function scrollTo (index) {
    /*
    * 报错Cannot read property 'offsetWidth' of undefined at Proxy.Scroller.scrollToElement
    * 因为当触摸move超出了侧边栏的总体高度限制的时候，那么touch.y2就会很大，那么最终求得的锚点索引anchorIndex也会很大
    * 导致滚动到元素的时候就找不到对应的元素了
    * 所以要保证index要在shortcutList的数组长度和0之间
    * */
    // 无效拖动就不去理会即可
    if (isNaN(index)) {
      return
    }
    // 最小值就是shortcutList的数组长度与index之间的最小的数 即为index的值不能超过数组长度
    index = Math.min(shortcutList.value.length - 1, index)
    // 求出锚点索引与0之间的最大值，即为最小值就是0，锚点索引不能为负
    index = Math.max(0, index)
    // 通过索引拿到需要滚动到的DOM元素
    const targetEl = groupRef.value.children[index]
    // 通过ref拿到scroll组件的实例，记得在setup中返回才可以
    // scrollRef.value对应的就是这个组件的实例，.scroll就是返回的scroll对象
    const scroll = scrollRef.value.scroll
    scroll.scrollToElement(targetEl, 0)
  }

  // 因为可能会返回更多东西，所以使用对象方式
  return {
    shortcutList,
    scrollRef,
    onShortcutTouchStart,
    onShortcutTouchMove
  }
}
